package com.leyou.search.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.SpecParam;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.search.client.CategoryClient;
import com.leyou.search.client.GoodsClient;
import com.leyou.search.client.SpecClient;
import com.leyou.search.pojo.Goods;
import com.leyou.search.respository.GoodsRepository;
import com.leyou.search.service.IndexService;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    private CategoryClient categoryClient;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private SpecClient specClient;

    @Autowired
    private GoodsRepository goodsRepository;

    @Autowired
    private IndexService indexService;

    @Override
    public Goods buildGoods(SpuBo spuBo) {
        Goods goods = new Goods();
        //对应拷贝对应的属性
        BeanUtils.copyProperties(spuBo, goods);
        //剩余四个属性没有被添加到索引库中,all,price,skus,specs
        //all:所有需要被搜索的信息，包含标题，分类，甚至品牌
        //跨服务查询分类信息
        List<String> names = this.categoryClient.queryNameByIds(Arrays.asList(spuBo.getCid1(), spuBo.getCid2(), spuBo.getCid3()));
//        String names = spuBo.getCname();
//        String all = spuBo.getTitle() + names;
        String all = spuBo.getTitle() + StringUtils.join(names, " ");
        goods.setAll(all);
        List<Sku> skus = goodsClient.querySkuBySpuId(spuBo.getId());
        //skus只需要id,title,price,和image,其他的都不需要,不能将整个sku存进去
        List<Map<String, Object>> skuMaps = new ArrayList<>();
        //处理价格
        List<Long> price = new ArrayList<>();
        skus.forEach(sku -> {
            //保存价格
            price.add(sku.getPrice());
            Map<String, Object> skuMap = new HashMap<>();
            skuMap.put("id", sku.getId());
            skuMap.put("title", sku.getTitle());
            skuMap.put("price", sku.getPrice());
            //每个sku只展示一个图片,图片的数据以逗号隔开
            skuMap.put("image", StringUtils.isBlank(sku.getImages()) ? "" : sku.getImages().split(",")[0]);
            //存储每一个sku
            skuMaps.add(skuMap);
        });
        goods.setSkus(JsonUtils.serialize(skuMaps));
        goods.setPrice(price);
        //处理spec
        //获取所有的可搜索的规格参数
        List<SpecParam> searchingParams = this.specClient.querySpecParams(null, null, true,null);
        //获取所有的特有规格参数和通用规格参数
        SpuDetail spuDetail = goodsClient.querySpuDetailById(spuBo.getId());
        //为了方便取值我们把通用规格参数和特有规格参数都转换为,map集合
        //通用规格参数
        Map<Long, Object> genericSpecMap = JsonUtils.nativeRead(spuDetail.getGenericSpec(), new TypeReference<Map<Long, Object>>() {
        });
        //特有规格参数
        Map<Long, List<String>> specialSpecMap = JsonUtils.nativeRead(spuDetail.getSpecialSpec(), new TypeReference<Map<Long, List<String>>>() {
        });
        HashMap<String, Object> spec = new HashMap<>();
        //遍历searchingParams
        searchingParams.forEach(specParam -> {
            Long id = specParam.getId();
            String name = specParam.getName();//具体的key值
            Object value = null;
            if (specParam.getGeneric()) {
                //从通用规格参数中取值
                value = genericSpecMap.get(id);
                if (null != value && specParam.getNumeric()) {
                    //得到的数值类型可能需要加分段,以及单位
                    value = this.chooseSegment(value.toString(), specParam);
                } else {
                    //从特有的规格参数中取值
                    value = specialSpecMap.get(id);
                }
                if (null == value) {
                    value = "其他";
                }
            }
            spec.put(name, value);
        });
        goods.setSpecs(spec);
        return goods;
    }

    /**
     * 创建或更新索引,这里的id是spu 的id,将spu转化为spuBo 在保存goods
     *
     * @param id
     */
    @Override
    public void createIndex(Long id) {
        SpuBo spuBo = new SpuBo();
        Spu spu = this.goodsClient.querySpuById(id);
        BeanUtils.copyProperties(spu, spuBo);
        Goods goods = this.indexService.buildGoods(spuBo);
        this.goodsRepository.save(goods);
    }

    /**
     * 删除索引
     *
     * @param id
     */
    @Override
    public void deleteIndex(Long id) {
        this.goodsRepository.deleteById(id);
    }

    private String chooseSegment(String value, SpecParam p) {
        double val = NumberUtils.toDouble(value);
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {//segment:1000-2000
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = NumberUtils.toDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if (segs.length == 2) {
                end = NumberUtils.toDouble(segs[1]);
            }
            // 判断是否在范围内
            if (val >= begin && val < end) {
                if (segs.length == 1) {
                    result = segs[0] + p.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segs[1] + p.getUnit() + "以下";
                } else {
                    result = segment + p.getUnit();//添加单位
                }
                break;
            }
        }
        return result;
    }
}
